package com.bjc.platform.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import com.bjc.platform.Constants;
import com.bjc.platform.dao.GenericDao;
import com.bjc.platform.model.AdmOrg;
import com.bjc.platform.model.AdmRole;
import com.bjc.platform.model.AdmUser;
import com.bjc.platform.model.CustomUserDetails;
import com.bjc.platform.repository.AdmUserRepo;
import com.bjc.platform.service.AdmUserService;
import com.bjc.platform.util.Page;
import com.bjc.platform.util.SqlUtil;
import com.bjc.platform.util.StaticMethod;
import com.bjc.platform.vo.AdmUserSearchCondition;
import com.bjc.platform.vo.AdmUserVo;

@Service("userService")
public class AdmUserServiceImpl extends BaseServiceImpl implements
		AdmUserService {
	// 查询有效用户信息HQL
	private static final String QUERY_ALL_VALID_USER = " select u from AdmUser u where u.flag = 1 ";
	// 根据角色查询有效用户信息HQL
	private static final String QUERY_ALL_VALID_USER_WITH_ROLE = " select u from AdmUser u left join u.roles r where r.id = :roleId and u.flag = 1 and r.flag = 1  ";
	@Autowired
	GenericDao genericDao;
	@Autowired
	private AdmUserRepo admUserRepo;

	public AdmUser findUserByUsername(String userName) {
		StringBuilder hql = new StringBuilder();
		hql.append(QUERY_ALL_VALID_USER);
		hql.append(" and u.username =:username");
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("username", userName);
		List<AdmUser> users = (List<AdmUser>) genericDao.queryByJpql(
				hql.toString(), params, null);
		if (users != null && users.size() == 1) {
			return users.get(0);
		} else {
			return null;
		}
	}

	/**
	 * 将用户实体对象转换为VO对象
	 * 
	 * @param user
	 * @return
	 */
	protected AdmUserVo admUser2AdmUserVo(AdmUser user) {
		AdmUserVo vo = new AdmUserVo();
		BeanUtils.copyProperties(user, vo);

		AdmOrg org = user.getOrgnize();
		String orgDesc = null;
		String rolesDesc = null;
		if (org != null) {
			orgDesc = org.getBelongOrg();
			if (orgDesc != null && orgDesc.length() > 0) {
				vo.setOrgDesc(orgDesc + "->" + org.getName());
			} else {
				vo.setOrgDesc(org.getName());
			}

			Long orgId = org.getId();
			vo.setOrgId(orgId);
		}
//
//		Employee employee = user.getEmployee();
//		if (employee != null) {
//			vo.setEmployeeId(employee.getId());
//			vo.setEmployeeName(employee.getName());
//			vo.setBirthday(employee.getBornDate());
//			vo.setFullName(employee.getName());
//			vo.setSex(Long.valueOf(employee.getSex()));
//		}

		if (user.getRoles() != null) {
			Set<AdmRole> roles = user.getRoles();
			StringBuilder roleIds = new StringBuilder();
			List<String> roleNames = new ArrayList<String>();
			boolean firstFlag = true;
			if (user.getRoles() != null) {
				for (AdmRole role : roles) {
					if (firstFlag) {
						firstFlag = false;
					} else {
						roleIds.append(",");
					}
					roleIds.append(role.getId());
					roleNames.add(role.getRoleName());
				}
				vo.setRoleIds(roleIds.toString());

				// 角色排序
				String[] arrayRoleNames = roleNames
						.toArray(new String[roleNames.size()]);
				Arrays.sort(arrayRoleNames);
				rolesDesc = Arrays.toString(arrayRoleNames);
				vo.setRolesDesc(rolesDesc.substring(1, rolesDesc.length() - 1));
			}
		}
		return vo;
	}

	@Override
	public AdmUser save(AdmUser user) {
		return admUserRepo.save(user);
	}

	@Override
	public AdmUser get(Long id) {
		return admUserRepo.findOne(id);
	}

	@Override
	public void delete(Long id) {
		admUserRepo.delete(id);
	}

	@Override
	public Page search(AdmUserSearchCondition cond, PageRequest pr) {
		CustomUserDetails user = StaticMethod.getUser();
		boolean isCompany = false;
		
		Page page = new Page();
		StringBuilder hql = new StringBuilder();
		Map<String, Object> param = new HashMap<String, Object>();

		if(user.getOrg() != null && !Constants.ORG_GROUP.equals(user.getOrg().getOrgnizeType())){
			isCompany = true;
		}
		
		if (cond == null) {
			hql.append(QUERY_ALL_VALID_USER);
		} else {
			if (cond.getRoleId() != null) {
				hql.append(QUERY_ALL_VALID_USER_WITH_ROLE);
				param.put("roleId", cond.getRoleId());
			} else {
				hql.append(QUERY_ALL_VALID_USER);
			}

			if (!StringUtils.isEmpty(cond.getFullname())) {
				hql.append(" and u.fullName like :fullname ");
				param.put("fullname", SqlUtil.wrapperLike(cond.getFullname()));
			}
			if (!StringUtils.isEmpty(cond.getUsername())) {
				hql.append(" and u.username like :username ");
				param.put("username", SqlUtil.wrapperLike(cond.getUsername()));
			}
		}
		
		if(isCompany){
			long companyId = user.getOrg().getCompanyId();
			hql.append(" and ( u.orgnize.id = ").append(companyId);
			hql.append(" or u.orgnize.companyId = ").append(companyId).append(")");
		}

		Long count = genericDao.countByJpql(hql.toString(), param);
		List result = genericDao.queryByJpql(hql.toString(), param, pr);
		List<AdmUserVo> vos = new ArrayList<AdmUserVo>();
		for (AdmUser u : (List<AdmUser>) result) {
			vos.add(admUser2AdmUserVo(u));
		}
		page.setTotalCount(count);
		page.setResult(vos);
		return page;
	}

	@Override
	public long getCountUserByRoleId(Long roleId) {
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("roleId", roleId);
		long count = genericDao.countByJpql(
				QUERY_ALL_VALID_USER_WITH_ROLE.toString(), param);
		return count;
	}

	@Override
	public int validUserCheck(AdmUser user) {
		StringBuilder sb = new StringBuilder();
		if (user != null) {
			sb.append(
					"from AdmUser u where u.flag = 1 and LOWER(u.username) = LOWER('")
					.append(user.getUsername()).append("')");
			if (user.getId() != null && user.getId() > 0) {
				sb.append(" and u.id <> ").append(user.getId());
			}

			Map<String, Object> params = null;
			long count = genericDao.countByJpql(sb.toString(), params);
			if (count > 0) {
				return EXIST_USER_NAME;
			}
		}

		return VALID_USER;
	}

}
